home *** CD-ROM | disk | FTP | other *** search
/ QuickTime 2.0 Developer Kit / QuickTime 2.0 Developer Kit.iso / pc / windows / qtw_201 / setup / samples / pviewer / framewnd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-12-19  |  38.1 KB  |  1,044 lines

  1.  
  2. // ---------------------------------------------------------------------
  3. //
  4. // FrameWnd.c - Picture Viewer - QuickTime for Windows
  5. //
  6. //              Version 1.0
  7. //
  8. //              (c) Copyright 1988-1994 Apple Computer, Inc. All Rights Reserved.
  9. //
  10. // ---------------------------------------------------------------------
  11.  
  12.  
  13. // Includes
  14. // --------
  15. #define NOMINMAX
  16. #include <Windows.H>  // Required by Windows
  17. #include <commdlg.h>  // Header file for common dlgs
  18. #include <dlgs.h>     // Header file for common dlgs ids
  19. #include <cderr.h>    // Header file for error ids
  20. #include <memory.h>   // Needed for memset() function
  21. #include <shellapi.h> // Drag and drop stuff
  22. #include <ver.h>
  23.  
  24. #include <qtole.h> // Interface to qtole dll
  25.  
  26. #include "fileexts.rh"
  27.  
  28. #include "common.h" // Interface to common.c
  29.  
  30. #include "viewer.h"  // Interface to other *.c files
  31. #include "viewer.hr" // Defines used in *.rc files
  32. #include "picture.h" // Interface to other *.c files
  33.  
  34. // Message-Persistent Data
  35. // -----------------------
  36. static struct // Hungarian notation: g
  37.   { HWND      hwndClient;      // MDI client window
  38.     WORD      wNumPictures;    // Number of picture wnds
  39.     BOOL      bUserAbortPrint; // User abort print flag
  40.     HWND      hwndCancelPrt;   // Handle of print cancel dlg
  41.     HBITMAP   hAboutBitmap;    // Temp static storage of bitmap
  42.                                // displayed in about dialogs
  43.   } g;
  44.  
  45.  
  46. // Exported callback functions
  47. // ----------------------------
  48. BOOL __export CALLBACK AboutDlgProc       (HWND, UINT, WPARAM, LPARAM);
  49. BOOL __export CALLBACK CloseEnumProc      (HWND, LPARAM);
  50. BOOL __export CALLBACK PaletteEnumProc    (HWND, LPARAM);
  51. BOOL __export CALLBACK PrintCancelDlgProc (HWND, UINT, WPARAM, LPARAM);
  52. int  __export CALLBACK PrintAbortProc     (HDC, int);
  53. UINT __export CALLBACK PrintDlgHookProc   (HWND, UINT, WPARAM, LPARAM);
  54.  
  55. // Internal Function Declarations
  56. // ------------------------------
  57. static LONG NEAR ViewerFrameCreate       (HWND);
  58. static LONG NEAR ViewerFileCommands      (HWND, WPARAM, WORD);
  59. static LONG NEAR ViewerWindowCommands    (HWND, WPARAM, WORD);
  60. static LONG NEAR ViewerHelpCommands      (HWND, WPARAM, WORD);
  61. static LONG NEAR LaunchPictureWnd        (LPSTR, LPSTR);
  62. static VOID NEAR ViewerEnableMenus       (HWND, BOOL);
  63. static VOID NEAR TellUserCommonDlgError  (DWORD);
  64. static LONG NEAR ProcessDroppedFiles     (HWND, WPARAM );
  65. static VOID NEAR DestroyHelpInstance     (HWND);
  66.  
  67. // -----------------------------------------------------------------------
  68.  
  69.  
  70. // Function: ViewerFrameWndProc - Viewer Frame Window Procedure
  71. // --------------------------------------------------------------------
  72. // Parameters: As required by Microsoft Windows
  73. //
  74. // Returns:    Via DefFrameProc
  75. // --------------------------------------------------------------------
  76. LONG __export CALLBACK ViewerFrameWndProc
  77.     (HWND hwndFrame, UINT message, WPARAM wParam, LPARAM lParam)
  78.  
  79. {
  80.     WNDENUMPROC       lpfnEnumPictures; // -> callback funcion for
  81.                                         // enumeration of pictures
  82.     HWND              hwndPicture;      // Temp handle of active picture wnd
  83.     LPQTOLE_OLEDATA   lpOleData;        // -> to OLE data
  84.  
  85.  
  86.     switch( message ) {
  87.         case WM_CREATE:
  88.             return ViewerFrameCreate( hwndFrame );
  89.  
  90.         case WM_PALETTECHANGED:
  91.             if( g.wNumPictures &&
  92.                 ( lpfnEnumPictures = (WNDENUMPROC) MakeProcInstance
  93.                 ( (FARPROC) PaletteEnumProc, ViewerQueryInstance()))) {
  94.                 StoreCurrentSystemPalette( NULL );
  95.  
  96.                 // Tell the picture wnds to repaint themselves
  97.                 EnumChildWindows( g.hwndClient, lpfnEnumPictures,
  98.                     (LPARAM) wParam);
  99.                 FreeProcInstance( (FARPROC) lpfnEnumPictures );
  100.             }
  101.  
  102.             return 0L;
  103.  
  104.         case WM_INITMENUPOPUP:
  105.             // Set check marks and enable menu items in popups
  106.             if( !(BOOL) HIWORD( lParam ) &&
  107.                 ( hwndPicture = (HWND) SendMessage
  108.                 ( g.hwndClient, WM_MDIGETACTIVE, 0, 0L )) &&
  109.                 IsWindow( hwndPicture ))
  110.                 SendMessage( hwndPicture,
  111.                 WM_VIEWER_INITPOPUPS, wParam, lParam );
  112.  
  113.             return 0L;
  114.  
  115.         case WM_COMMAND:
  116.             switch( wParam ) {
  117.                 case VIEWER_FILE_OPEN: // file menu popup
  118.                 case VIEWER_FILE_CLOSE:
  119.                 case VIEWER_FILE_PRTSETUP:
  120.                 case VIEWER_FILE_PRINT:
  121.                 case VIEWER_FILE_EXIT:
  122.                     return ViewerFileCommands
  123.                         ( hwndFrame, wParam, HIWORD (lParam));
  124.  
  125.                 case VIEWER_WINDOW_TILE: // window menu popup
  126.                 case VIEWER_WINDOW_CASCADE:
  127.                 case VIEWER_WINDOW_ARRANGE:
  128.                     return ViewerWindowCommands
  129.                         ( hwndFrame, wParam, HIWORD (lParam));
  130.  
  131.  
  132.                 case VIEWER_HELP_VIEWERHELP: // help menu popup
  133.                 case VIEWER_HELP_USINGHELP:
  134.                 case VIEWER_HELP_ABOUTVIEWER:
  135.                     return ViewerHelpCommands
  136.                         ( hwndFrame, wParam, HIWORD (lParam));
  137.  
  138.                 default:
  139.                     if( ( hwndPicture = (HWND) SendMessage
  140.                         ( g.hwndClient, WM_MDIGETACTIVE, 0, 0L )) &&
  141.                         IsWindow( hwndPicture ))
  142.                         SendMessage( hwndPicture,
  143.                         WM_COMMAND, wParam, lParam );
  144.  
  145.                     break; // break to DefFrameProc
  146.             }
  147.  
  148.             break;
  149.  
  150.         // WM_USER messages
  151.  
  152.         case WM_VIEWER_CMDLINE:
  153.             return LaunchPictureWnd( (LPSTR) lParam, NULL );
  154.  
  155.         case WM_VIEWER_PICTUREDELETED:
  156.             // Decrement picture count. This is incremented in LaunchPictureWnd
  157.             // when picture is created
  158.             if( --g.wNumPictures <= 0 )
  159.                 ViewerEnableMenus( hwndFrame, FALSE );
  160.             return 0L;
  161.  
  162.         // These next messages are posted by the ole callback function in PictUtl.c
  163.         case WM_VIEWER_OLE_OPTIONSDLG:
  164.             ViewerGetOptions( NULL, (LPQTOLE_OPTIONSPICTURE) lParam );
  165.             return 0L;
  166.  
  167.         case WM_VIEWER_OLE_PLAYOBJECT:
  168.             QTOLE_PlayObject( ViewerQueryOleData(), lParam );
  169.             return 0L;
  170.  
  171.  
  172.         // end WM_USER messages
  173.  
  174.  
  175.         // Standard drag and drop processing. Allows for multiple pictures but
  176.         // does not worry about position of drop
  177.         case WM_DROPFILES:
  178.             return ProcessDroppedFiles( hwndFrame, wParam );
  179.  
  180.         case WM_QUERYENDSESSION:
  181.         case WM_CLOSE:
  182.             if( g.wNumPictures &&
  183.                 ( lpfnEnumPictures = (WNDENUMPROC) MakeProcInstance
  184.                 ( (FARPROC) CloseEnumProc, ViewerQueryInstance()))) { // Give all pictures a chance to stop the close
  185.                 EnumChildWindows( g.hwndClient, lpfnEnumPictures, 0L );
  186.                 FreeProcInstance( (FARPROC) lpfnEnumPictures );
  187.  
  188.                 // If someone didn't want to close, don't kill the app
  189.                 if( NULL != GetWindow( g.hwndClient, GW_CHILD ))
  190.                     return 0L;
  191.             }
  192.  
  193.             // Tell qtole.dll that we are closing the server
  194.             // Don't close if QTOLE_ClosingServerWnd returns FALSE;
  195.             if( ( lpOleData = ViewerQueryOleData()) &&
  196.                 lpOleData->lpqtoleServer &&
  197.                 !QTOLE_ClosingServerWnd( lpOleData, message ))
  198.                 return 0L;
  199.  
  200.             break; // break to DefFrameProc
  201.  
  202.  
  203.         case WM_NCDESTROY:
  204.             DragAcceptFiles( hwndFrame, FALSE );
  205.  
  206.             // Destroy help instance
  207.             DestroyHelpInstance( hwndFrame );
  208.  
  209.             // NULL the global hwnds in viewmain.c
  210.             ViewerNoMoreWindow();
  211.  
  212.             PostQuitMessage( 0 );
  213.             break;
  214.  
  215.     }
  216.  
  217.     return DefFrameProc
  218.         ( hwndFrame, g.hwndClient, message, wParam, lParam );
  219. }
  220.  
  221.  
  222. // Function: ViewerFrameCreate - process WM_CREATE message
  223. // --------------------------------------------------------------------
  224. // Parameters: HWND hwndFrame;         Frame window
  225. //
  226. // Returns:    0L if OK, else returns -1L to kill app
  227. // --------------------------------------------------------------------
  228. static LONG NEAR ViewerFrameCreate( HWND hwndFrame )
  229.  
  230. {
  231.     CLIENTCREATESTRUCT  clientcreate;  // MDI client create struct
  232.     char                szCaption[50]; // caption buffer;
  233.  
  234.  
  235.     szCaption[0] = '\0';
  236.     if( LoadString( ViewerQueryResources(), VIEWER_STRING_CAPTION,
  237.         szCaption, sizeof( szCaption )))
  238.         SetWindowText( hwndFrame, szCaption );
  239.     // No point in trying for an error message here since it probably won't
  240.     // load either.
  241.  
  242.     // disable menu items until a picture is created
  243.     g.wNumPictures = 0;
  244.     ViewerEnableMenus( hwndFrame, FALSE );
  245.  
  246.     DragAcceptFiles( hwndFrame, TRUE );
  247.  
  248.     clientcreate.hWindowMenu =
  249.         GetSubMenu( GetMenu( hwndFrame ), MENU_WINDOW_POS );
  250.     clientcreate.idFirstChild = VIEWER_CLIENT_FIRSTCHILD;
  251.  
  252.     if( !(g.hwndClient = CreateWindow( "MDICLIENT", NULL,
  253.         WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE |
  254.         WS_HSCROLL | WS_VSCROLL ,
  255.         0, 0, 0, 0, hwndFrame, ( HMENU) 1,
  256.         ViewerQueryInstance(), (LPVOID) &clientcreate )))
  257.         return -1L; // return -1 to kill app
  258.     else
  259.         return  0L;
  260. }
  261.  
  262.  
  263. // Function: ViewerFileCommands - Process WM_COMMAND, File popup messages
  264. // --------------------------------------------------------------------
  265. // Parameters: HWND   hwndFrame;      Frame window
  266. //             WORD   wIDItem;        Menu or control id
  267. //             WORD   wNotifyCode;    notification message
  268. //
  269. // Returns:    LONG   generally 0L
  270. // --------------------------------------------------------------------
  271. static LONG NEAR ViewerFileCommands
  272.                     (HWND hwndFrame, WPARAM wIDItem, WORD wNotifyCode )
  273.  
  274. {
  275.     HWND          hwndPicture;                 // Handle of picture window
  276.     OPENFILENAME  ofn;                         // OPENFILENAME struct
  277.     char          szPicturePath[MAX_PATH_LEN]; // Picture file path.
  278.                                                // Must be at least 256 bytes
  279.     char          szPictureName[MAX_NAME_LEN]; // Picture file name
  280.     char          szFilter[MAX_PATH_LEN];      // Picture file filter str
  281.     DWORD         dwError;                     // Common dlg error return
  282.     PRINTDLG      pd;                          // Print common dlg struct
  283.     ABORTPROC     lpPrintAbortProc;            // -> to Print abort proc
  284.     DLGPROC       lpPrtCancelProc;             // -> to Print cancel dlg proc
  285.     WORD          wIDError;                    // Resource error string id
  286.     int           nError;                      // Error return
  287.     UINT          uSavErrMode;
  288.     HINSTANCE     hLibrary;
  289.  
  290.     typedef UINT ( CALLBACK * PRINTDLGHOOKPROC ) ( HWND, UINT, WPARAM, LPARAM );
  291.     typedef BOOL (FAR PASCAL *PGETOPENFILENAMEPREVIEW) (LPOPENFILENAME lpofn);
  292.  
  293.     PGETOPENFILENAMEPREVIEW pGetOpenFileNamePreview = NULL;
  294.  
  295.     static DWORD  dwFilterIndex = 1; // Filter index. Saved between
  296.  
  297.  
  298.     switch( wIDItem ) {
  299.         case VIEWER_FILE_OPEN:
  300.             memset( &ofn, 0, sizeof( OPENFILENAME ));
  301.             szPicturePath[0] = '\0'; 
  302.  
  303.             CommonGetFileFilter (ViewerQueryInstance (), (WORD) COMMON_PICTURES_FILEEXT, szFilter, sizeof szFilter);
  304.  
  305.             ofn.lStructSize    = sizeof( OPENFILENAME );
  306.             ofn.hwndOwner      = hwndFrame;
  307.             ofn.lpstrFilter    = szFilter;
  308.             ofn.nFilterIndex   = dwFilterIndex;
  309.             ofn.lpstrFile      = szPicturePath;
  310.             ofn.nMaxFile       = sizeof( szPicturePath );
  311.             ofn.lpstrFileTitle = szPictureName;
  312.             ofn.nMaxFileTitle  = sizeof( szPictureName );
  313.             ofn.Flags =
  314.                 OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
  315.  
  316.             uSavErrMode = SetErrorMode (SEM_NOOPENFILEERRORBOX);
  317.  
  318.             if ((hLibrary = LoadLibrary ("msvideo.dll")) >= HINSTANCE_ERROR) {
  319.                 pGetOpenFileNamePreview = (PGETOPENFILENAMEPREVIEW) GetProcAddress (hLibrary, "#252");
  320.                 pGetOpenFileNamePreview = NULL;
  321.             }
  322.  
  323.             if (pGetOpenFileNamePreview != NULL) {
  324.                 if( (*pGetOpenFileNamePreview) ( &ofn )) {
  325.                     dwFilterIndex = ofn.nFilterIndex;
  326.                     LaunchPictureWnd( szPicturePath, szPictureName );
  327.                 }
  328.                 else if( dwError = CommDlgExtendedError() ) { // Tell the user about the error
  329.                     TellUserCommonDlgError( dwError );
  330.                 }
  331.             }
  332.  
  333.             else {
  334.                 if( GetOpenFileName ( &ofn )) {
  335.                     dwFilterIndex = ofn.nFilterIndex;
  336.                     LaunchPictureWnd( szPicturePath, szPictureName );
  337.                 }
  338.                 else if( dwError = CommDlgExtendedError() ) { // Tell the user about the error
  339.                     TellUserCommonDlgError( dwError );
  340.                 }
  341.             }
  342.  
  343.             if (hLibrary >= HINSTANCE_ERROR)
  344.                 FreeLibrary (hLibrary);
  345.             SetErrorMode (uSavErrMode);
  346.  
  347.             return 0L;
  348.  
  349.         case VIEWER_FILE_CLOSE:
  350.             if( ( hwndPicture = (HWND) SendMessage
  351.                 ( g.hwndClient, WM_MDIGETACTIVE, 0, 0L )) &&
  352.                 IsWindow( hwndPicture ))
  353.                 SendMessage( hwndPicture, WM_CLOSE, 0, 0L );
  354.  
  355.             return 0L;
  356.  
  357.         case VIEWER_FILE_PRTSETUP:
  358.             memset( &pd, 0, sizeof( PRINTDLG ));
  359.  
  360.             pd.lStructSize = sizeof( PRINTDLG );
  361.             pd.hwndOwner   = hwndFrame;
  362.             pd.Flags       = PD_PRINTSETUP;
  363.  
  364.             if( ( PrintDlg( &pd ) == 0 ) &&
  365.                 ( dwError = CommDlgExtendedError())) { // Tell the user about the error
  366.                 TellUserCommonDlgError( dwError );
  367.             }
  368.  
  369.             return 0L;
  370.  
  371.         case VIEWER_FILE_PRINT:
  372.             // Customize the common dlg to eliminate some options that are
  373.             // not useful. This requires a new template and a hook proc
  374.             memset( &pd, 0, sizeof( PRINTDLG ));
  375.  
  376.             pd.lStructSize = sizeof( PRINTDLG );
  377.             pd.hwndOwner   = hwndFrame;
  378.             pd.Flags       = PD_RETURNDC |
  379.                 PD_ENABLEPRINTHOOK | PD_ENABLEPRINTTEMPLATE;
  380.             pd.hInstance   = ViewerQueryResources();
  381.             pd.lpPrintTemplateName = MAKEINTRESOURCE( CUSTOM_DLG_COMN_PRINT );
  382.             if( !( pd.lpfnPrintHook =  (PRINTDLGHOOKPROC)
  383.                 MakeProcInstance( (FARPROC) PrintDlgHookProc,
  384.                 ViewerQueryInstance()))) {
  385.                 CommonTellUser( ViewerQueryResources(),
  386.                     VIEWER_STRING_NOMEMORY, NULL, MB_OK );
  387.                 return 0L;
  388.             }
  389.  
  390.             if( PrintDlg( &pd ) != 0 ) {
  391.                 lpPrtCancelProc = (DLGPROC) MakeProcInstance
  392.                     ( (FARPROC) PrintCancelDlgProc, ViewerQueryInstance() );
  393.  
  394.                 lpPrintAbortProc = (ABORTPROC) MakeProcInstance
  395.                     ( (FARPROC) PrintAbortProc, ViewerQueryInstance() );
  396.  
  397.                 if( !lpPrtCancelProc || !lpPrintAbortProc ) {
  398.                     CommonTellUser( ViewerQueryResources(),
  399.                         VIEWER_STRING_NOMEMORY, NULL, MB_OK );
  400.                     return 0L;
  401.                 }
  402.  
  403.                 g.bUserAbortPrint = FALSE;
  404.                 nError   = 0;
  405.                 wIDError = 0;
  406.  
  407.                 if( !(g.hwndCancelPrt =
  408.                     CreateDialog( ViewerQueryResources(),
  409.                     MAKEINTRESOURCE( VIEWER_DLG_PRINTCANCEL ),
  410.                     hwndFrame, lpPrtCancelProc ))) {
  411.                     wIDError = VIEWER_STRING_CANCELDLG;
  412.                 }
  413.                 else {
  414.                     EnableWindow( hwndFrame, FALSE ); // disable frame window
  415.  
  416.                     if( SetAbortProc( pd.hDC, lpPrintAbortProc ) <= 0 )
  417.                         wIDError = VIEWER_STRING_ABORTPROC;
  418.                     else {
  419.                         if( hwndPicture = (HWND) SendMessage
  420.                             ( g.hwndClient, WM_MDIGETACTIVE, 0, 0L ))
  421.                             nError = (int) SendMessage( hwndPicture,
  422.                             WM_VIEWER_PRINTPICTURE, 0,
  423.                             (LPARAM) (LPPRINTDLG) &pd );
  424.                         if( ( nError < 0 ) &&
  425.                             ( nError & SP_NOTREPORTED ) &&
  426.                             !g.bUserAbortPrint ) {
  427.                             switch( nError ) {
  428.                                 case SP_APPABORT:
  429.                                 case SP_USERABORT:
  430.                                     break;
  431.                                 case SP_OUTOFDISK:
  432.                                     wIDError = VIEWER_STRING_PRT_OUTOFDISK;
  433.                                     break;
  434.                                 case SP_OUTOFMEMORY:
  435.                                     wIDError = VIEWER_STRING_PRT_NOMEMORY;
  436.                                     break;
  437.                                 case SP_ERROR: // fall through
  438.                                 default:
  439.                                     wIDError = VIEWER_STRING_PRT_GENERROR;
  440.                                     break;
  441.                             }
  442.                         }
  443.                     }
  444.  
  445.                     // reenable frame window
  446.                     EnableWindow( hwndFrame, TRUE );
  447.  
  448.                     if( g.hwndCancelPrt )
  449.                         DestroyWindow( g.hwndCancelPrt );
  450.                 }
  451.  
  452.                 if( wIDError )
  453.                     CommonTellUser( ViewerQueryResources(), wIDError,
  454.                     VIEWER_STRING_PRT_CAPTION, MB_OK );
  455.  
  456.                 FreeProcInstance( (FARPROC) lpPrtCancelProc );
  457.                 FreeProcInstance( (FARPROC) lpPrintAbortProc );
  458.  
  459.                 if( pd.hDC )
  460.                     DeleteDC( pd.hDC );
  461.                 if( pd.hDevMode != NULL )
  462.                     GlobalFree( pd.hDevMode );
  463.                 if( pd.hDevNames != NULL )
  464.                     GlobalFree( pd.hDevNames );
  465.             }
  466.             else if( dwError = CommDlgExtendedError()) { // Tell the user about the error
  467.                 TellUserCommonDlgError( dwError );
  468.             }
  469.  
  470.             return 0L;
  471.  
  472.         case VIEWER_FILE_EXIT:
  473.             SendMessage( hwndFrame, WM_CLOSE, 0, 0L );
  474.             return 0L;
  475.     }
  476.  
  477.     return 0L; // should never get here
  478.  
  479. }
  480.  
  481.  
  482. // Function: ViewerWindowCommands - Process WM_COMMAND, Window popup messages
  483. // --------------------------------------------------------------------
  484. // Parameters: HWND   hwndFrame;      Frame window
  485. //             WORD   wIDItem;        Menu or control id
  486. //             WORD   wNotifyCode;    notification message
  487. //
  488. // Returns:    LONG   generally 0L
  489. // --------------------------------------------------------------------
  490. static LONG NEAR ViewerWindowCommands
  491.                     (HWND hwndFrame, WPARAM wIDItem, WORD wNotifyCode )
  492.  
  493. // This is standard MDI stuff.
  494. {
  495.     switch( wIDItem ) {
  496.         case VIEWER_WINDOW_TILE:
  497.             SendMessage( g.hwndClient, WM_MDITILE, 0, 0L );
  498.             return 0L;
  499.  
  500.         case VIEWER_WINDOW_CASCADE:
  501.             SendMessage( g.hwndClient, WM_MDICASCADE, 0, 0L );
  502.             return 0L;
  503.  
  504.         case VIEWER_WINDOW_ARRANGE:
  505.             SendMessage( g.hwndClient, WM_MDIICONARRANGE, 0, 0L );
  506.             return 0L;
  507.     }
  508.  
  509.     return 0L; // should never get here
  510.  
  511. }
  512.  
  513.  
  514. // Function: ViewerHelpCommands - Process WM_COMMAND, Help popup messages
  515. // --------------------------------------------------------------------
  516. // Parameters: HWND   hwndFrame;      Frame window
  517. //             WORD   wIDItem;        Menu or control id
  518. //             WORD   wNotifyCode;    notification message
  519. //
  520. // Returns:    LONG   generally 0L
  521. // --------------------------------------------------------------------
  522. static LONG NEAR ViewerHelpCommands
  523.                     (HWND hwndFrame, WPARAM wIDItem, WORD wNotifyCode )
  524.  
  525. {
  526.     char       szHelp[MAX_PATH_LEN]; // Help file path
  527.     DLGPROC    lpDlgProc;            // -> dialog proc
  528.  
  529.     switch( wIDItem ) {
  530.         case VIEWER_HELP_VIEWERHELP:
  531.             CommonGetLocalizedHelpFile
  532.                 ( VIEWER_ROOT_NAME, szHelp, ViewerQueryInstance() );
  533.  
  534.             if( szHelp[0] )
  535.                 WinHelp( hwndFrame, (LPCSTR) szHelp, HELP_CONTENTS, 0L );
  536.             else
  537.                 CommonTellUser( ViewerQueryResources(),
  538.                 VIEWER_STRING_NOHELPFILE,
  539.                 VIEWER_STRING_CAPTION, MB_OK );
  540.  
  541.             return 0L;
  542.  
  543.         case VIEWER_HELP_USINGHELP:
  544.             WinHelp( hwndFrame, (LPCSTR) "WINHELP.HLP", HELP_CONTENTS, 0L );
  545.             return 0L;
  546.  
  547.         case VIEWER_HELP_ABOUTVIEWER:
  548.             if( ( g.hAboutBitmap = LoadBitmap( ViewerQueryResources(),
  549.                 MAKEINTRESOURCE( VIEWER_VIEWER_BITMAP ))) &&
  550.                 ( lpDlgProc = (DLGPROC) MakeProcInstance
  551.                 ( (FARPROC) AboutDlgProc, ViewerQueryInstance()))) {
  552.                 DialogBox( ViewerQueryResources(),
  553.                     MAKEINTRESOURCE( VIEWER_DLG_ABOUTVIEWER ),
  554.                     hwndFrame, lpDlgProc );
  555.                 FreeProcInstance( (FARPROC) lpDlgProc );
  556.             }
  557.             else
  558.                 CommonTellUser( ViewerQueryResources(),
  559.                 VIEWER_STRING_NOMEMORY,
  560.                 VIEWER_STRING_CAPTION, MB_OK );
  561.             if( g.hAboutBitmap )
  562.                 DeleteObject( g.hAboutBitmap );
  563.             g.hAboutBitmap = NULL;
  564.  
  565.             return 0L;
  566.     }
  567.  
  568.     return 0L; // should never get here
  569.  
  570. }
  571.  
  572.  
  573. // Function: CloseEnumProc - Close all enumerate proc
  574. // --------------------------------------------------------------------
  575. // Parameters: As required by Microsoft Windows
  576. //
  577. // Returns:    Always TRUE to enumerate all windows
  578. // --------------------------------------------------------------------
  579. BOOL __export CALLBACK CloseEnumProc( HWND hwnd, LPARAM lParam )
  580.  
  581. {
  582.     char    szClassName[40]; // Temp buffer for class name
  583.  
  584.     // Check class name since there are several classes of child windows
  585.     // These include scroll bars etc that appear in picture windows
  586.     if( !GetClassName( hwnd, szClassName, sizeof( szClassName )) ||
  587.         lstrcmpi( szClassName, VIEWER_PICTURE_CLASS ))
  588.         return TRUE;
  589.  
  590.     // If someone doesn't want to quit, stop enumeration
  591.     if( !SendMessage( hwnd, WM_QUERYENDSESSION, 0, 0L ))
  592.         return FALSE;
  593.  
  594.     SendMessage( GetParent( hwnd ), WM_MDIDESTROY, (WPARAM) hwnd, 0L );
  595.  
  596.     return TRUE;
  597. }
  598.  
  599. // Function: PaletteEnumProc - Tells all child wnds to repaint because
  600. //                             of palette change
  601. // --------------------------------------------------------------------
  602. // Parameters: As required by Microsoft Windows
  603. //
  604. // Returns:    Always TRUE to enumerate all windows
  605. // --------------------------------------------------------------------
  606. BOOL __export CALLBACK PaletteEnumProc( HWND hwnd, LPARAM lParam )
  607.  
  608. {
  609.     char    szClassName[40]; // Temp buffer for class name
  610.  
  611.     // Check class name since there are several classes of child windows
  612.     // These include scroll bars etc that appear in picture windows
  613.     if( !GetClassName( hwnd, szClassName, sizeof( szClassName )) ||
  614.         lstrcmpi( szClassName, VIEWER_PICTURE_CLASS ))
  615.         return TRUE;
  616.  
  617.     if( hwnd != (HWND) LOWORD( lParam ))
  618.         InvalidateRect( hwnd, NULL, FALSE );
  619.  
  620.     return TRUE;
  621. }
  622.  
  623.  
  624. // Function: LaunchPictureWnd - tell hwndClient to launch a picture wnd
  625. // --------------------------------------------------------------------
  626. // Parameters: LPSTR    lpPicturePath        Path of picture file
  627. //             LPSTR    lpName               File name of picture
  628. //
  629. // Returns:    LONG     generally 0L
  630. // --------------------------------------------------------------------
  631. static LONG NEAR LaunchPictureWnd( LPSTR lpPicturePath, LPSTR lpName )
  632.  
  633. {
  634.     MDICREATESTRUCT       mdicreate;   // mdi create struct
  635.     HWND                  hwndPicture; // Temp handle of window
  636.  
  637.     if( !lpPicturePath[0] )
  638.         return -1L;
  639.  
  640.     if( lpName == NULL ) {
  641.         lpName = lpPicturePath + lstrlen( lpPicturePath );
  642.         lpName = AnsiPrev( lpPicturePath, lpName );
  643.         while( *lpName && (*lpName != '\\') && (lpName != lpPicturePath))
  644.             lpName = AnsiPrev( lpPicturePath, lpName );
  645.         if( *lpName == '\\' )
  646.             lpName = AnsiNext( lpName );
  647.     }
  648.  
  649.     mdicreate.szClass = VIEWER_PICTURE_CLASS;
  650.     mdicreate.szTitle = lpName;
  651.     mdicreate.hOwner  = ViewerQueryInstance();
  652.     mdicreate.x       = CW_USEDEFAULT;
  653.     mdicreate.y       = CW_USEDEFAULT;
  654.     mdicreate.cx      = CW_USEDEFAULT;
  655.     mdicreate.cy      = CW_USEDEFAULT;
  656.     mdicreate.style   = MDIS_ALLCHILDSTYLES | WS_CLIPCHILDREN;
  657.     mdicreate.lParam  = (LPARAM) lpPicturePath;
  658.  
  659.     if( !( hwndPicture = (HWND) SendMessage
  660.         ( g.hwndClient, WM_MDICREATE, 0,
  661.         (LPARAM) (LPMDICREATESTRUCT) &mdicreate ))) {
  662.         return -1L;
  663.     }
  664.     else {
  665.         if(++g.wNumPictures == 1 )
  666.             ViewerEnableMenus( ViewerQueryFrameWindow(), TRUE );
  667.  
  668.         return 0L;
  669.     }
  670. }
  671.  
  672.  
  673. // Function: ProcessDroppedFiles - Process the WM_DROPFILES message
  674. // --------------------------------------------------------------------
  675. // Parameters: HWND     hwndFrame         Frame window handle
  676. //             WPARAM   wParam            Message wParam
  677. //
  678. // Returns:    LONG     Always 0L;
  679. // --------------------------------------------------------------------
  680. static LONG NEAR ProcessDroppedFiles( HWND hwndFrame, WPARAM wParam )
  681.  
  682. {
  683.     int           i;                        // Temp counter
  684.     int           nNumFiles;                // Temp number of dropped files
  685.     UINT          uBytes;                   // Temp len of drop file path
  686.     char          szDropFile[MAX_PATH_LEN]; // Temp drop file path
  687.  
  688.     if( nNumFiles = DragQueryFile( (HDROP) wParam, 0xffff,
  689.         (LPSTR) NULL, 0 )) { // Create processing requires that frame window has
  690.                              // nonzero dimensions so first restore iconic window
  691.         if( IsIconic( hwndFrame ))
  692.             ShowWindow( hwndFrame, SW_SHOWNORMAL );
  693.  
  694.         for( i=0; i < nNumFiles; i++ ) {
  695.             uBytes = DragQueryFile( (HDROP) wParam, i,
  696.                 (LPSTR) szDropFile, sizeof( szDropFile ));
  697.             if( uBytes > 0 )
  698.                 LaunchPictureWnd( szDropFile, NULL );
  699.         }
  700.     }
  701.  
  702.     DragFinish( (HDROP) wParam );
  703.  
  704.     return 0L;
  705. }
  706.  
  707. // Function: DestroyHelpInstance - Tell windows that instance is done with
  708. //                                 help. This is called as a function so that
  709. //                                 szHelp[] is not an automatic var. in the
  710. //                                 winproc
  711. // --------------------------------------------------------------------
  712. // Parameters: HWND     hwndFrame         Frame window handle
  713. //
  714. // Returns:    VOID
  715. // --------------------------------------------------------------------
  716. static VOID NEAR DestroyHelpInstance( HWND hwndFrame )
  717.  
  718. {
  719.     char          szHelp[MAX_PATH_LEN]; // Help file name
  720.  
  721.     WinHelp( hwndFrame, CommonGetLocalizedHelpFile
  722.         ( VIEWER_ROOT_NAME, szHelp, ViewerQueryResources() ),
  723.         HELP_QUIT, NULL );
  724.     return;
  725. }
  726.  
  727. // Function: AboutDlgProc - About dialog proc
  728. // --------------------------------------------------------------------
  729. // Parameters: As required by Microsoft Windows
  730. //
  731. // Returns:    As required by Microsoft Windows
  732. // --------------------------------------------------------------------
  733. BOOL __export CALLBACK AboutDlgProc
  734.                   ( HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam )
  735.  
  736. {
  737.     BITMAP       bm;          // Temp bitmap struct
  738.     HWND         hwndCntrl;   // Handle of rect control that is painted
  739.                               // over with bitmap
  740.     HDC          hdestDC;     // hdc of control rect
  741.     HDC          hmemDC;      // Memory dc
  742.     RECT         rcdestRect;  // Rect of control
  743.     HBITMAP      hbitmapSave; // return from select object
  744.     PAINTSTRUCT  ps;          // Paint struct
  745.     char         szFormat[80];
  746.     char         szBuffer[80];
  747.     DWORD        handle;
  748.     DWORD        dwSize;
  749.     UINT         uiSize;
  750.     LPBYTE       lpBuffer;
  751.  
  752.     static BYTE  abData[1024];
  753.  
  754.  
  755.     switch( msg ) {
  756.         case WM_COMMAND:
  757.             EndDialog( hdlg, 0 );
  758.             return TRUE;
  759.  
  760.         case WM_INITDIALOG:
  761.             GetModuleFileName (ViewerQueryResources(), szBuffer, sizeof szBuffer);
  762.             dwSize = GetFileVersionInfoSize (szBuffer, &handle);
  763.             GetFileVersionInfo (szBuffer, handle, dwSize, abData);
  764.             VerQueryValue ((VOID FAR *) abData, (LPCSTR) "\\StringFileInfo\\040904E4\\ProductVersion", (VOID FAR * FAR *) &lpBuffer, (UINT FAR *) &uiSize);
  765.             GetDlgItemText (hdlg, ABOUT_VERSION, szFormat, sizeof szFormat);
  766.             wsprintf (szBuffer, szFormat, (LPSTR) lpBuffer);
  767.             SetDlgItemText (hdlg, ABOUT_VERSION, szBuffer);
  768.             GetDlgItemText (hdlg, ABOUT_VERSION_REQUIRES, szFormat, sizeof szFormat);
  769.             wsprintf (szBuffer, szFormat, (LPSTR) lpBuffer);
  770.             SetDlgItemText (hdlg, ABOUT_VERSION_REQUIRES, szBuffer);
  771.             return TRUE;
  772.  
  773.         case WM_PAINT:
  774.             // Don't bother with error messages since only effect is that
  775.             // bitmap will not appear in dialog
  776.             if( !BeginPaint( hdlg, &ps ))
  777.                 return FALSE;
  778.             EndPaint( hdlg, &ps );
  779.  
  780.             if( !g.hAboutBitmap ||
  781.                 !( hwndCntrl = GetDlgItem( hdlg, VIEWER_ABOUT_BMPFRAME )))
  782.                 return FALSE;
  783.  
  784.             InvalidateRect( hwndCntrl, NULL, TRUE );
  785.             UpdateWindow( hwndCntrl );
  786.  
  787.             if( !(hdestDC = GetDC( hwndCntrl )))
  788.                 return FALSE;
  789.  
  790.             if( hmemDC = CreateCompatibleDC( hdestDC )) {
  791.                 if( hbitmapSave = SelectObject( hmemDC, g.hAboutBitmap )) {
  792.                     GetObject( g.hAboutBitmap, sizeof( BITMAP ), &bm );
  793.                     GetClientRect( hwndCntrl, &rcdestRect );
  794.  
  795.                     BitBlt( hdestDC,
  796.                         ( rcdestRect.right - bm.bmWidth ) / 2,
  797.                         ( rcdestRect.bottom - bm.bmHeight ) / 2,
  798.                         bm.bmWidth, bm.bmHeight, hmemDC, 0, 0, SRCCOPY );
  799.  
  800.                     SelectObject( hmemDC, hbitmapSave );
  801.                 }
  802.  
  803.                 DeleteDC( hmemDC );
  804.             }
  805.  
  806.             ReleaseDC( hwndCntrl, hdestDC );
  807.  
  808.             return FALSE;
  809.  
  810.         default:
  811.             return FALSE;
  812.     }
  813.  
  814.     return FALSE;
  815. }
  816.  
  817.  
  818. // Function: PrintAbortProc - Print abort proc
  819. // --------------------------------------------------------------------
  820. // Parameters: As required by Microsoft Windows
  821. //
  822. // Returns:    As required by Microsoft Windows
  823. // --------------------------------------------------------------------
  824. int __export CALLBACK PrintAbortProc( HDC hdc, int nCode )
  825.  
  826. {
  827.     MSG     msg; // Message struct
  828.  
  829.     while( !g.bUserAbortPrint &&
  830.         PeekMessage( &msg, NULL, NULL, NULL, PM_REMOVE )) {
  831.         if( !g.hwndCancelPrt || !IsDialogMessage( g.hwndCancelPrt, &msg )) {
  832.             TranslateMessage( &msg );
  833.             DispatchMessage( &msg );
  834.         }
  835.     }
  836.  
  837.     return !g.bUserAbortPrint;
  838. }
  839.  
  840. // Function: PrintCancelDlgProc - User cancel printing dlg proc
  841. // --------------------------------------------------------------------
  842. // Parameters: As required by Microsoft Windows
  843. //
  844. // Returns:    As required by Microsoft Windows
  845. // --------------------------------------------------------------------
  846. BOOL __export CALLBACK PrintCancelDlgProc
  847.                   ( HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam )
  848.  
  849. {
  850.     char    szName[50]; // Buffer for picture name
  851.  
  852.     switch( msg ) {
  853.         case WM_INITDIALOG:
  854.             SetFocus( GetDlgItem( hdlg, IDCANCEL ));
  855.             SetDlgItemText( hdlg, PRINT_CANCEL_PICTURENAME,
  856.                 ViewerQueryActivePictureName( szName ));
  857.             return TRUE;
  858.  
  859.         case WM_COMMAND:
  860.             return ( g.bUserAbortPrint = TRUE );
  861.  
  862.         case WM_DESTROY:
  863.             g.hwndCancelPrt = NULL;
  864.             break;
  865.     }
  866.  
  867.     return FALSE;
  868. }
  869.  
  870.  
  871. // Function: PrintDlgHookProc - Custom print common dlg hook function
  872. // --------------------------------------------------------------------
  873. // Parameters: As required by Microsoft Windows
  874. //
  875. // Returns:    As required by Microsoft Windows
  876. // --------------------------------------------------------------------
  877. UINT __export CALLBACK PrintDlgHookProc
  878.                 (HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam )
  879.  
  880. { // The dialog ids are defined in dlgs.h
  881.   // Array of ids of controls to be hidden
  882.     static int nIDs[] = {grp1, rad1, rad2, rad3, stc2, edt1,
  883.                          stc3, edt2, chx1, chx2, pshHelp };
  884.     UINT   i; // Temp counter
  885.  
  886.     if( message == WM_INITDIALOG ) {
  887.         for( i=0; i < ( sizeof( nIDs ) / sizeof( nIDs[0] )); i++ )
  888.             ShowWindow( GetDlgItem( hdlg, nIDs[i] ), SW_HIDE );
  889.  
  890.         return TRUE;
  891.     }
  892.     else
  893.         return FALSE;
  894. }
  895.  
  896.  
  897. // Function: ViewerEnableMenus - Disables menu items when there
  898. //                               are no pictures
  899. // --------------------------------------------------------------------
  900. // Parameters: HWND       hwndFrame      Handle of frame window
  901. //             BOOL       bEnable        Enabling flag
  902. //
  903. // Returns:    VOID
  904. // --------------------------------------------------------------------
  905. static VOID NEAR ViewerEnableMenus( HWND hwndFrame, BOOL bEnable )
  906.  
  907. {
  908.     UINT    fFlag;      // Temp enabling flag
  909.     HMENU   hmenuFrame; // Handle to main menu of frame window
  910.     UINT    i;          // Index
  911.  
  912.     static UINT uMenuIDs[] = {VIEWER_FILE_CLOSE,
  913.                               VIEWER_FILE_PRINT,
  914.  
  915.                               VIEWER_EDIT_COPYPICTURE,
  916.                               VIEWER_EDIT_OPTIONS,
  917.                               VIEWER_EDIT_CANCELSEL,
  918.  
  919.                               VIEWER_IMAGE_GETINFO,
  920.                               VIEWER_IMAGE_HALFSIZE,
  921.                               VIEWER_IMAGE_NORMALSIZE,
  922.                               VIEWER_IMAGE_DOUBLESIZE,
  923.  
  924.                               VIEWER_WINDOW_TILE,
  925.                               VIEWER_WINDOW_CASCADE,
  926.                               VIEWER_WINDOW_ARRANGE
  927.                              };
  928.  
  929.     if( !( hmenuFrame = GetMenu( hwndFrame )))
  930.         return;
  931.  
  932.     fFlag = (bEnable ? MF_ENABLED : MF_GRAYED ) | MF_BYCOMMAND;
  933.     for( i=0; i < sizeof( uMenuIDs ) / sizeof( uMenuIDs[0] ); i++ )
  934.         EnableMenuItem( hmenuFrame, uMenuIDs[i], fFlag );
  935.  
  936.     DrawMenuBar( hwndFrame );
  937.  
  938.     return;
  939. }
  940.  
  941.  
  942. // Function: TellUserCommonDlgError - Tell the user about the common dlg
  943. //                                    error
  944. // --------------------------------------------------------------------
  945. // Parameters: DWORD       dwError      error code returned by common dlg
  946. //
  947. // Returns:    VOID
  948. // --------------------------------------------------------------------
  949. static VOID NEAR TellUserCommonDlgError( DWORD dwError )
  950.  
  951. {
  952.     WORD          wIDErrorString; // String id
  953.  
  954.     // Not much here now, can make this as explicit as desired
  955.     // Now returns text of error id, i.e. "CDERR_INITIALIZATION"
  956.     // Not all messages are explicitly included
  957.  
  958.     switch( dwError ) {
  959.         case CDERR_FINDRESFAILURE:
  960.             wIDErrorString = VIEWER_STRING_CDLG_FINDRESFAIL;
  961.             break;
  962.         case CDERR_INITIALIZATION:
  963.             wIDErrorString = VIEWER_STRING_CDLG_INITFAIL;
  964.             break;
  965.         case CDERR_LOADRESFAILURE:
  966.             wIDErrorString = VIEWER_STRING_CDLG_LOADRESFAIL;
  967.             break;
  968.         case CDERR_LOCKRESFAILURE:
  969.             wIDErrorString = VIEWER_STRING_CDLG_LOCKRESFAIL;
  970.             break;
  971.         case CDERR_MEMALLOCFAILURE:
  972.             wIDErrorString = VIEWER_STRING_CDLG_MEMALLOCFAIL;
  973.             break;
  974.         case CDERR_MEMLOCKFAILURE:
  975.             wIDErrorString = VIEWER_STRING_CDLG_MEMLOCKFAIL;
  976.             break;
  977.         case CDERR_STRUCTSIZE:
  978.             wIDErrorString = VIEWER_STRING_CDLG_STRUCTSIZE;
  979.             break;
  980.         case FNERR_INVALIDFILENAME:
  981.             wIDErrorString = VIEWER_STRING_CDLG_BADFILENAME;
  982.             break;
  983.         case PDERR_INITFAILURE:
  984.             wIDErrorString = VIEWER_STRING_CDLG_PRTINITFAIL;
  985.             break;
  986.         case PDERR_LOADDRVFAILURE:
  987.             wIDErrorString = VIEWER_STRING_CDLG_LOADDRVFAIL;
  988.             break;
  989.         case PDERR_NODEFAULTPRN:
  990.             wIDErrorString = VIEWER_STRING_CDLG_NODEFPRINTER;
  991.             break;
  992.         case PDERR_NODEVICES:
  993.             wIDErrorString = VIEWER_STRING_CDLG_NODEVICES;
  994.             break;
  995.         case PDERR_PRINTERNOTFOUND:
  996.             wIDErrorString = VIEWER_STRING_CDLG_NOFINDPNTR;
  997.             break;
  998.         case PDERR_SETUPFAILURE:
  999.             wIDErrorString = VIEWER_STRING_CDLG_SETUPFAIL;
  1000.             break;
  1001.         default:
  1002.             wIDErrorString = VIEWER_STRING_CDLG_GENFAILURE;
  1003.             break;
  1004.     }
  1005.  
  1006.     if( wIDErrorString == VIEWER_STRING_CDLG_GENFAILURE )
  1007.         CommonTellUser( ViewerQueryResources(),
  1008.         VIEWER_STRING_CDLG_GENFAILURE,
  1009.         VIEWER_STRING_CDLG_CAP, MB_OK, dwError );
  1010.     else
  1011.         CommonTellUser( ViewerQueryResources(),
  1012.         VIEWER_STRING_CDLG_FORMAT, VIEWER_STRING_CDLG_CAP,
  1013.         MB_OK, wIDErrorString );
  1014.     return;
  1015.  
  1016. }
  1017.  
  1018.  
  1019. //  The remaining functions are the query functions called by other modules
  1020.  
  1021. // Function: ViewerQueryClientWindow - Query Client Window Handle
  1022. // --------------------------------------------------------------------
  1023. // Parameters: None.
  1024. //
  1025. // Returns:    HWND g.hwndClient;        MDI client window handle
  1026. // --------------------------------------------------------------------
  1027. HWND FAR ViewerQueryClientWindow( VOID )
  1028.  
  1029. {
  1030.     return g.hwndClient;
  1031. }
  1032.  
  1033. // Function: ViewerQueryNumPictures - Query number of pictures
  1034. // --------------------------------------------------------------------
  1035. // Parameters: None.
  1036. //
  1037. // Returns:    HWND g.wNumPictures;    Number of pictures
  1038. // --------------------------------------------------------------------
  1039. WORD FAR ViewerQueryNumPictures( VOID )
  1040.  
  1041. {
  1042.     return g.wNumPictures;
  1043. }
  1044.